package setting

import (
	"log"
	"time"

	"github.com/go-ini/ini"
	"github.com/go-redis/redis"
)

type EmailConfig struct {
	From      string
	Addr      string
	SendEmail string
	SendPass  string
	SendSTMP  string
}

type Autocode struct {
	TransferRestart bool   `mapstructure:"transfer-restart" json:"transfer-restart" yaml:"transfer-restart"`
	Root            string `mapstructure:"root" json:"root" yaml:"root"`
	Server          string `mapstructure:"server" json:"server" yaml:"server"`
	SApi            string `mapstructure:"server-api" json:"server-api" yaml:"server-api"`
	SPlug           string `mapstructure:"server-plug" json:"server-plug" yaml:"server-plug"`
	SInitialize     string `mapstructure:"server-initialize" json:"server-initialize" yaml:"server-initialize"`
	SModel          string `mapstructure:"server-model" json:"server-model" yaml:"server-model"`
	SRequest        string `mapstructure:"server-request" json:"server-request"  yaml:"server-request"`
	SRouter         string `mapstructure:"server-router" json:"server-router" yaml:"server-router"`
	SService        string `mapstructure:"server-service" json:"server-service" yaml:"server-service"`
	Web             string `mapstructure:"web" json:"web" yaml:"web"`
	WApi            string `mapstructure:"web-api" json:"web-api" yaml:"web-api"`
	WForm           string `mapstructure:"web-form" json:"web-form" yaml:"web-form"`
	WTable          string `mapstructure:"web-table" json:"web-table" yaml:"web-table"`
}

var (
	Cfg *ini.File

	RunMode      string
	HTTPPort     int
	ReadTimeout  time.Duration
	WriteTimeout time.Duration

	PageSize      int
	JwtSecret     string
	JwtBufferTime int64

	RedisInstance *redis.Client

	UseCaptcha bool

	EmailObject EmailConfig
	AutoCode    Autocode
)

func init() {
	var err error
	Cfg, err = ini.Load("conf/app.ini")
	if err != nil {
		log.Fatalf("Fail to parse 'conf/app.ini': %v", err)
	}

	LoadBase()
	LoadServer()
	LoadApp()
	LoadRedis()
	LoadEmail()
	LoadAutoCode()
}

func LoadBase() {
	RunMode = Cfg.Section("").Key("RUN_MODE").MustString("debug")
}

func LoadServer() {
	sec, err := Cfg.GetSection("server")
	if err != nil {
		log.Fatalf("Fail to get section 'server': %v", err)
	}

	HTTPPort = sec.Key("HTTP_PORT").MustInt(8000)
	ReadTimeout = time.Duration(sec.Key("READ_TIMEOUT").MustInt(60)) * time.Second
	WriteTimeout = time.Duration(sec.Key("WRITE_TIMEOUT").MustInt(60)) * time.Second
}

func LoadApp() {
	sec, err := Cfg.GetSection("app")
	if err != nil {
		log.Fatalf("Fail to get section 'app': %v", err)
	}

	JwtSecret = sec.Key("JWT_SECRET").MustString("ssss111")
	JwtBufferTime = sec.Key("JWT_BUFFERTIME").MustInt64(1000)
	PageSize = sec.Key("PAGE_SIZE").MustInt(10)
	UseCaptcha = sec.Key("USE_CAPTCHA").MustBool(false)
}

func LoadRedis() {
	sec, err := Cfg.GetSection("redis")
	if err != nil {
		log.Fatalf("Fail to get section 'app': %v", err)
	}

	redisHost := sec.Key("HOST").MustString("")
	redisDB := sec.Key("DB").MustInt(0)
	redisPassword := sec.Key("PASSWORD").MustString("")

	client := redis.NewClient(&redis.Options{
		Addr:     redisHost,
		Password: redisPassword, // no password set
		DB:       redisDB,       // use default DB
	})
	_, err = client.Ping().Result()
	if err != nil {
		log.Fatalf("Fail to connect redis : %v", err)
	} else {
		log.Print("redis pong comming!")
		RedisInstance = client
	}
}

func LoadEmail() {
	emailConfig, err := Cfg.GetSection("email")
	if err != nil {
		log.Fatalf("Fail to get section 'app': %v", err)
	}

	EmailObject = EmailConfig{
		From:      emailConfig.Key("FROM").MustString(""),
		Addr:      emailConfig.Key("ADDR").MustString(""),
		SendEmail: emailConfig.Key("SENDEMAIL").MustString(""),
		SendPass:  emailConfig.Key("SENDPASS").MustString(""),
		SendSTMP:  emailConfig.Key("SENDSTMP").MustString(""),
	}
}

func LoadAutoCode() {
	cfg, err := Cfg.GetSection("autocode")
	if err != nil {
		log.Fatalf("Fail to get section 'app': %v", err)
	}

	AutoCode = Autocode{
		Root:        cfg.Key("Root").MustString(""),
		Server:      cfg.Key("server").MustString(""),
		SInitialize: cfg.Key("server-initialize").MustString(""),
		SApi:        cfg.Key("server-api").MustString(""),
		SRouter:     cfg.Key("server-router").MustString(""),
		SService:    cfg.Key("server-service").MustString(""),
	}
}
